package gen_demo

import "fmt"

func reverse[t any](s []t) []t {
	sLen := len(s)
	result := make([]t, sLen)
	for i, item := range s {
		result[sLen-i-1] = item
	}
	return result
}

func ReverseDemo() {
	fmt.Println(reverse([]int{1, 2, 3, 4}))
}

func min[T int | float64](a, b T) T {
	if a < b {
		return a
	} else {
		return b
	}
}

func MinDemo() {
	fmt.Println(min(3, 2))
	i := min[int](3, 2)
	fmt.Println(i)

	m := min[float64]
	fmt.Println(m(1.2, 2.2))
}

type Sayable[T int | float64 | string] interface {
	Say() T
}

type Person[T int | float64 | string] struct {
	msg T
}

func (p Person[T]) Say() T {
	return p.msg
}

func SayDemo() {
	var s Sayable[string]
	s = Person[string]{"hello world"}
	fmt.Println(s.Say())
}

// MyMap类型定义了两个类型形参 KEY 和 VALUE。分别为两个形参指定了不同的类型约束
type MyMap[KEY int | string, VALUE float32 | float64] map[KEY]VALUE

func MapDemo() {
	var mm MyMap[string, float64] = map[string]float64{
		"hello world": 42.0,
		"world":       3.0,
	}
	fmt.Println(mm)
}

type WordStruct[T int | float64, S []T] struct {
	Data     S
	MaxValue T
	MinValue T
}

func WsDemo() {
	w := WordStruct[int, []int]{[]int{1, 2}, 2, 4}
	fmt.Println(w)
}

type NewType[T interface{ *int | *float64 }] []T

func NewTypeDemo() {
	n := make(NewType[*float64], 10)
	a := 10.1
	n2 := append(n, &a)
	fmt.Println(n2)
}

type MySlice[T int | float64] []T

func (s MySlice[T]) Sum() T {
	var res T
	for _, v := range s {
		res += v
	}
	return res
}

func MySliceDemo() {
	ms := MySlice[int]([]int{1, 2, 3})
	fmt.Println(ms.Sum())
}
